package com.chenbei.erp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenbei.erp.domain.Inventory;
import com.chenbei.erp.domain.InventoryLog;
import com.chenbei.erp.enums.InventoryTransactionTypeEnum;
import com.chenbei.erp.vo.InventoryVo;
import com.chenbei.erp.vo.req.InventoryReq;
import com.chenbei.erp.mapper.InventoryMapper;
import com.chenbei.erp.service.IInventoryLogService;
import com.chenbei.erp.service.IInventoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Objects;

@Slf4j
@Service
public class InventoryService extends ServiceImpl<InventoryMapper, Inventory> implements IInventoryService {

    @Autowired
    private IInventoryLogService inventoryLogService;

    @Override
    public Page<Inventory> pageList(InventoryReq InventoryReq) {
        LambdaQueryWrapper<Inventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(Inventory::getId);
        if (InventoryReq.getProductId() != null && InventoryReq.getProductId() > 0) {
            lambdaQueryWrapper.eq(Inventory::getProductId, InventoryReq.getProductId());
        }
        if (InventoryReq.getWarehouseStorageAreaId() != null && InventoryReq.getWarehouseStorageAreaId() > 0) {
            lambdaQueryWrapper.eq(Inventory::getStorageLocationId, InventoryReq.getWarehouseStorageAreaId());
        }

        Page<Inventory> pageConfig = new Page<>(InventoryReq.getPageNum(), InventoryReq.getPageSize());
        return page(pageConfig, lambdaQueryWrapper);
    }

    @Override
    @Transactional
    public void saveOrUpdate(InventoryVo inventoryVo) {
        LambdaQueryWrapper<Inventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Inventory::getStorageLocationId, inventoryVo.getStorageLocationId())
                .eq(Inventory::getProductId, inventoryVo.getProductId()).last("LIMIT 1");
        Inventory Inventory = getOne(lambdaQueryWrapper);
        Long inventoryId = null;
        if (Inventory != null) {
            if (Objects.equals(inventoryVo.getTransactionType(), InventoryTransactionTypeEnum.INBOUND.getType())) {
                Inventory.setQuantity(Inventory.getQuantity() + inventoryVo.getProductNumber());
            } else {
                Inventory.setQuantity(Inventory.getQuantity() - inventoryVo.getProductNumber());
            }
            updateById(Inventory);
            inventoryId = Inventory.getId();
        } else {
            Inventory newInventory = new Inventory();
            if (Objects.equals(inventoryVo.getTransactionType(), InventoryTransactionTypeEnum.INBOUND.getType())) {
                newInventory.setQuantity(inventoryVo.getProductNumber());
            } else {
                newInventory.setQuantity(-inventoryVo.getProductNumber());
            }
            newInventory.setCreateTime(LocalDateTime.now());
            newInventory.setProductId(inventoryVo.getProductId());
            newInventory.setStorageLocationId(inventoryVo.getStorageLocationId());

            save(newInventory);
            inventoryId = newInventory.getId();
        }

        InventoryLog InventoryLog = new InventoryLog();
        InventoryLog.setInventoryId(inventoryId);
        InventoryLog.setTransactionType(inventoryVo.getTransactionType());
        InventoryLog.setQuantity(inventoryVo.getProductNumber());
        InventoryLog.setRemarks(inventoryVo.getRemark());
        InventoryLog.setCreateTime(LocalDateTime.now());

        inventoryLogService.add(InventoryLog);
    }

    @Override
    public Long getProductQuantity(Long storageLocationId, Long productId) {
        LambdaQueryWrapper<Inventory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Inventory::getProductId, productId)
                .eq(Inventory::getStorageLocationId, storageLocationId)
                .last("LIMIT 1");
        Inventory Inventory = getOne(lambdaQueryWrapper);
        if (Inventory == null) {
            return 0L;
        } else {
            return Inventory.getQuantity() == null ? 0L : Inventory.getQuantity();
        }
    }
}
